import { _decorator, Component, Node, Sprite, UITransform } from 'cc'
import { TILE_CONFIGS } from '../utils/constants'
import { DIRECTION_ENUM, DIRECTION_ORDER_ENUM, EVENT_NAME_ENUM, ENTITY_STATE_ENUM, ENTITY_TYPE_ENUM } from '../enums'
import EventMgr from '../runtime/EventMgr'
import { PlayerStateMachine } from './PlayerStateMachine'
import { EntityMgr } from '../base/EntityMgr'
import DataMgr from '../runtime/DataMgr'
import { IEntity } from '../levels'
const { ccclass, property } = _decorator
/** 玩家管理器 实际创建玩家的逻辑 */
// 紧记 地图是以左上角为原点，向下y轴是负数，往左x轴是正数的坐标图
@ccclass('PlayerMgr')
export class PlayerMgr extends EntityMgr {
  targetX: number = 0 // 目标X轴位置
  targetY: number = 0 // 目标Y轴位置
  isMoving: boolean = false // 玩家是否正在移动
  private readonly speed: number = 0.1

  async init(initData: IEntity) {
    // 添加状态机
    this.fsm = this.addComponent(PlayerStateMachine)
    await this.fsm.init() // 初始化状态机参数

    // 使用父类的init方法
    super.init(initData)
    this.targetX = this.x
    this.targetY = this.y

    EventMgr.Instance.on(EVENT_NAME_ENUM.CONTROLLER_MOVE, this.inputHandle, this)
    EventMgr.Instance.on(EVENT_NAME_ENUM.ATTACK_PLAYER, this.handlePlayerDead, this) // 触发攻击玩家的事件
  }

  update(): void {
    this.updateXY()
    super.update()
  }

  // 更新实际的坐标
  updateXY() {
    if (this.x < this.targetX) {
      this.x += this.speed
    } else if (this.x > this.targetX) {
      this.x -= this.speed
    }
    if (this.y < this.targetY) {
      this.y += this.speed
    } else if (this.y > this.targetY) {
      this.y -= this.speed
    }

    if (Math.abs(this.x - this.targetX) < 0.1 && Math.abs(this.y - this.targetY) < 0.1 && this.isMoving) {
      this.isMoving = false // 移动结束，标记设为false
      this.x = this.targetX
      this.y = this.targetY
      EventMgr.Instance.emit(EVENT_NAME_ENUM.PLAYER_MOVE_END) // 触发玩家移动结束事件
    }
  }

  // 玩家死亡
  handlePlayerDead(state: ENTITY_STATE_ENUM) {
    this.state = state
  }

  // 移动前的判断，判断是否可以进行移动
  inputHandle(inputDirection: DIRECTION_ENUM) {
    // 死亡后、玩家攻击时不能移动玩家
    if (
      this.state === ENTITY_STATE_ENUM.DEATH ||
      this.state === ENTITY_STATE_ENUM.AIRDEATH ||
      this.state === ENTITY_STATE_ENUM.ATTACK
    ) {
      return
    }
    // 判断是否发起攻击
    const enemyId = this.willAttack(inputDirection)
    if (enemyId) {
      EventMgr.Instance.emit(EVENT_NAME_ENUM.ATTACK_ENEMY, enemyId) // 触发攻击敌人事件
      EventMgr.Instance.emit(EVENT_NAME_ENUM.OPEN_DOOR, enemyId) // 触发门打开事件
      return
    }
    // 检测是否会碰到障碍
    if (this.willBlock(inputDirection)) {
      if (inputDirection === DIRECTION_ENUM.TOP) {
        EventMgr.Instance.emit(EVENT_NAME_ENUM.SCREEN_SHAKE, DIRECTION_ENUM.TOP) // 地图向上触发震动
      } else if (inputDirection === DIRECTION_ENUM.BOTTOM) {
        EventMgr.Instance.emit(EVENT_NAME_ENUM.SCREEN_SHAKE, DIRECTION_ENUM.BOTTOM) // 地图向下触发震动
      } else if (inputDirection === DIRECTION_ENUM.LEFT) {
        EventMgr.Instance.emit(EVENT_NAME_ENUM.SCREEN_SHAKE, DIRECTION_ENUM.LEFT) // 地图向左触发震动
      } else if (inputDirection === DIRECTION_ENUM.RIGHT) {
        EventMgr.Instance.emit(EVENT_NAME_ENUM.SCREEN_SHAKE, DIRECTION_ENUM.RIGHT) // 地图向右触发震动
      } else if (inputDirection === DIRECTION_ENUM.TURNLEFT) {
        EventMgr.Instance.emit(EVENT_NAME_ENUM.SCREEN_SHAKE, DIRECTION_ENUM.TURNLEFT) // 地图向左触发震动
      } else if (inputDirection === DIRECTION_ENUM.TURNRIGHT) {
        EventMgr.Instance.emit(EVENT_NAME_ENUM.SCREEN_SHAKE, DIRECTION_ENUM.TURNRIGHT)
      }

      return
    }

    this.move(inputDirection)
  }

  // 移动时更新目标坐标
  move(inputDirection: DIRECTION_ENUM) {
    // console.log(DataMgr.Instance.tileInfo)
    // 整个地图的坐标0点是在左上角 所以y轴方向的坐标是反的
    if (inputDirection === DIRECTION_ENUM.LEFT) {
      this.targetX -= 1
      this.isMoving = true
      this.showSmoke(inputDirection)
    } else if (inputDirection === DIRECTION_ENUM.RIGHT) {
      this.targetX += 1
      this.isMoving = true
      this.showSmoke(inputDirection)
    } else if (inputDirection === DIRECTION_ENUM.TOP) {
      this.targetY += 1
      this.isMoving = true
      this.showSmoke(inputDirection)
    } else if (inputDirection === DIRECTION_ENUM.BOTTOM) {
      this.targetY -= 1
      this.isMoving = true
      this.showSmoke(inputDirection)
    } else if (inputDirection === DIRECTION_ENUM.TURNLEFT) {
      // 切换方向
      if (this.direction === DIRECTION_ENUM.TOP) {
        this.direction = DIRECTION_ENUM.LEFT
      } else if (this.direction === DIRECTION_ENUM.LEFT) {
        this.direction = DIRECTION_ENUM.BOTTOM
      } else if (this.direction === DIRECTION_ENUM.BOTTOM) {
        this.direction = DIRECTION_ENUM.RIGHT
      } else if (this.direction === DIRECTION_ENUM.RIGHT) {
        this.direction = DIRECTION_ENUM.TOP
      }
      this.state = ENTITY_STATE_ENUM.TURNLEFT
      EventMgr.Instance.emit(EVENT_NAME_ENUM.PLAYER_MOVE_END) // 触发玩家移动结束事件
    } else if (inputDirection === DIRECTION_ENUM.TURNRIGHT) {
      // 切换方向
      if (this.direction === DIRECTION_ENUM.TOP) {
        this.direction = DIRECTION_ENUM.RIGHT
      } else if (this.direction === DIRECTION_ENUM.BOTTOM) {
        this.direction = DIRECTION_ENUM.LEFT
      } else if (this.direction === DIRECTION_ENUM.LEFT) {
        this.direction = DIRECTION_ENUM.TOP
      } else if (this.direction === DIRECTION_ENUM.RIGHT) {
        this.direction = DIRECTION_ENUM.BOTTOM
      }
      this.state = ENTITY_STATE_ENUM.TURNRIGHT
      EventMgr.Instance.emit(EVENT_NAME_ENUM.PLAYER_MOVE_END) // 触发玩家移动结束事件
    }
  }

  // 触发移动时烟雾显示的事件
  showSmoke(inputDirection: DIRECTION_ENUM) {
    // 传入当前玩家位置、按键方向，决定烟雾位置
    EventMgr.Instance.emit(EVENT_NAME_ENUM.SHOW_SMOKE, this.x, this.y, inputDirection)
  }

  willAttack(inputDirection: DIRECTION_ENUM): string {
    // 获取敌人数组 过滤死亡的敌人
    const enemies = DataMgr.Instance.enemies.filter(item => item.state !== ENTITY_STATE_ENUM.DEATH)
    for (let i = 0; i < enemies.length; i++) {
      const enemy = enemies[i]

      if (
        inputDirection === DIRECTION_ENUM.TOP &&
        this.direction === DIRECTION_ENUM.TOP &&
        enemy.x === this.x &&
        enemy.y === this.y + 2
      ) {
        // 当前玩家方向向上，按键输入也是向上，敌人的x轴等于玩家的x轴，敌人所在的y轴处于玩家上方2格----攻击
        this.state = ENTITY_STATE_ENUM.ATTACK
        return enemy.id
      } else if (
        inputDirection === DIRECTION_ENUM.BOTTOM &&
        this.direction === DIRECTION_ENUM.BOTTOM &&
        enemy.x === this.x &&
        enemy.y === this.y - 2
      ) {
        // 当前玩家方向向下，按键输入也是向下，敌人的x轴等于玩家的x轴，敌人所在的y轴处于玩家下方2格----攻击
        this.state = ENTITY_STATE_ENUM.ATTACK
        return enemy.id
      } else if (
        inputDirection === DIRECTION_ENUM.LEFT &&
        this.direction === DIRECTION_ENUM.LEFT &&
        enemy.x === this.x - 2 &&
        enemy.y === this.y
      ) {
        // 当前玩家方向向左，按键输入也是向左，敌人的y轴等于玩家的y轴，敌人所在的x轴处于玩家左方2格----攻击
        this.state = ENTITY_STATE_ENUM.ATTACK
        return enemy.id
      } else if (
        inputDirection === DIRECTION_ENUM.RIGHT &&
        this.direction === DIRECTION_ENUM.RIGHT &&
        enemy.x === this.x + 2 &&
        enemy.y === this.y
      ) {
        // 当前玩家方向向右，按键输入也是向右，敌人的y轴等于玩家的y轴，敌人所在的x轴处于玩家右方2格----攻击
        this.state = ENTITY_STATE_ENUM.ATTACK
        return enemy.id
      }
    }

    return null
  }

  // 判断是否可以移动 碰到障碍不能移动
  // 紧记 地图是以左上角为原点，向下y轴是负数，往左x轴是正数的坐标图
  willBlock(inputDirection: DIRECTION_ENUM) {
    const { targetX: x, targetY: y, direction } = this
    const { tileInfo } = DataMgr.Instance
    const { mapRowCount: row, mapColumnCount: column } = DataMgr.Instance // 地图的行列
    const enemies = DataMgr.Instance.enemies.filter(enemy => enemy.state !== ENTITY_STATE_ENUM.DEATH) // 获取活着的敌人
    const { x: doorX, y: doorY, state: doorState } = DataMgr.Instance.door || {} // 获取门的坐标数据和状态
    const bursts = DataMgr.Instance.bursts.filter(burst => burst.state !== ENTITY_STATE_ENUM.DEATH) // 获取可以使用的陷阱

    // 按钮方向 向上
    if (inputDirection === DIRECTION_ENUM.TOP) {
      const playerNextY = y + 1 // 玩家向上走时的下一个瓦片地图y坐标、

      // 玩家方向 向上
      if (direction === DIRECTION_ENUM.TOP) {
        // 不能向上走到没有瓦片的区域
        if (playerNextY > 0) {
          this.state = ENTITY_STATE_ENUM.BLOCKFRONT
          return true
        }

        const weaponNextY = y + 2 // 玩家向上走时武器的下一个瓦片地图y坐标 武器在玩家前一个格子 因为拿在手上
        const nextPlayerTile = tileInfo[x]?.[Math.abs(playerNextY)] // 获取玩家的下一个瓦片地图信息
        const nextWeaponTile = tileInfo[x]?.[Math.abs(weaponNextY)] // 获取武器的下一个瓦片地图信息

        // 检测是否碰撞到门
        if (
          ((doorX === x && doorY === playerNextY) || (doorX === x && doorY === weaponNextY)) &&
          doorState !== ENTITY_STATE_ENUM.DEATH
        ) {
          this.state = ENTITY_STATE_ENUM.BLOCKFRONT
          return true
        }
        // 检测是否碰撞到敌人
        // for (let i = 0; i < enemies.length; i++) {
        //   const enemy = enemies[i]
        //   const { x: enemyX, y: enemyY } = enemy
        //   if ((enemyX === x && enemyY === weaponNextY) || (enemyX === x && enemyY === playerNextY)) {
        //     this.state = ENTITY_STATE_ENUM.BLOCKFRONT
        //     return true
        //   }
        // }
        // 判断地裂陷阱
        if (
          bursts.some(burst => burst.x === x && burst.y === playerNextY) &&
          (!nextWeaponTile || nextWeaponTile.turnable)
        ) {
          return false
        }
        // 检测地图元素 碰撞
        if (nextPlayerTile && nextPlayerTile.moveable && (!nextWeaponTile || nextWeaponTile.turnable)) {
          // empty
        } else {
          this.state = ENTITY_STATE_ENUM.BLOCKFRONT
          return true
        }

        // 玩家方向 向下
      } else if (direction === DIRECTION_ENUM.BOTTOM) {
        // 判断是否超出地图
        if (playerNextY > 0) {
          this.state = ENTITY_STATE_ENUM.BLOCKBACK
          return true
        }

        const weaponNextY = y
        const nextPlayerTile = tileInfo[x]?.[Math.abs(playerNextY)]
        const nextWeaponTile = tileInfo[x]?.[Math.abs(weaponNextY)]

        // 检测是否碰撞到门
        if (
          ((doorX === x && doorY === playerNextY) || (doorX === x && doorY === weaponNextY)) &&
          doorState !== ENTITY_STATE_ENUM.DEATH
        ) {
          this.state = ENTITY_STATE_ENUM.BLOCKBACK
          return true
        }

        // 检测是否碰撞到敌人
        for (let i = 0; i < enemies.length; i++) {
          const enemy = enemies[i]
          const { x: enemyX, y: enemyY } = enemy

          if (enemyX === x && enemyY === playerNextY) {
            this.state = ENTITY_STATE_ENUM.BLOCKBACK
            return true
          }
        }

        // 检测地图元素 碰撞
        if (nextPlayerTile && nextPlayerTile.moveable && (!nextWeaponTile || nextWeaponTile.turnable)) {
          // empty
        } else {
          this.state = ENTITY_STATE_ENUM.BLOCKBACK
          return true
        }

        // 玩家方向——向左
      } else if (direction === DIRECTION_ENUM.LEFT) {
        // 判断是否超出地图
        if (playerNextY > 0) {
          this.state = ENTITY_STATE_ENUM.BLOCKRIGHT
          return true
        }

        const weaponNextX = x - 1
        const weaponNextY = y + 1
        const nextPlayerTile = tileInfo[x]?.[Math.abs(playerNextY)]
        const nextWeaponTile = tileInfo[weaponNextX]?.[Math.abs(weaponNextY)]

        // 检测是否碰撞到门
        if (
          ((doorX === x && doorY === playerNextY) || (doorX === weaponNextX && doorY === weaponNextY)) &&
          doorState !== ENTITY_STATE_ENUM.DEATH
        ) {
          this.state = ENTITY_STATE_ENUM.BLOCKRIGHT
          return true
        }

        // 检测是否碰撞到敌人
        for (let i = 0; i < enemies.length; i++) {
          const enemy = enemies[i]
          const { x: enemyX, y: enemyY } = enemy
          if ((enemyX === x && enemyY === playerNextY) || (enemyX === weaponNextX && enemyY === weaponNextY)) {
            this.state = ENTITY_STATE_ENUM.BLOCKRIGHT
            return true
          }
        }
        // 检测地图元素 碰撞
        if (nextPlayerTile && nextPlayerTile.moveable && (!nextWeaponTile || nextWeaponTile.turnable)) {
          // empty
        } else {
          this.state = ENTITY_STATE_ENUM.BLOCKRIGHT
          return true
        }

        //玩家方向 向右
      } else if (direction === DIRECTION_ENUM.RIGHT) {
        //判断是否超出地图
        if (playerNextY > 0) {
          this.state = ENTITY_STATE_ENUM.BLOCKLEFT
          return true
        }

        const weaponNextX = x + 1
        const weaponNextY = y + 1
        const nextPlayerTile = tileInfo[x]?.[Math.abs(playerNextY)]
        const nextWeaponTile = tileInfo[weaponNextX]?.[Math.abs(weaponNextY)]

        // 检测是否碰撞到门
        if (
          ((doorX === x && doorY === playerNextY) || (doorX === weaponNextX && doorY === weaponNextY)) &&
          doorState !== ENTITY_STATE_ENUM.DEATH
        ) {
          this.state = ENTITY_STATE_ENUM.BLOCKLEFT
          return true
        }

        // 检测是否碰撞到敌人
        for (let i = 0; i < enemies.length; i++) {
          const enemy = enemies[i]
          const { x: enemyX, y: enemyY } = enemy

          if ((enemyX === x && enemyY === playerNextY) || (enemyX === weaponNextX && enemyY === weaponNextY)) {
            this.state = ENTITY_STATE_ENUM.BLOCKLEFT
            return true
          }
        }
        // 检测地图元素 碰撞
        if (nextPlayerTile && nextPlayerTile.moveable && (!nextWeaponTile || nextWeaponTile.turnable)) {
          // empty
        } else {
          this.state = ENTITY_STATE_ENUM.BLOCKLEFT
          return true
        }
      }

      // 按钮方向——向下
    } else if (inputDirection === DIRECTION_ENUM.BOTTOM) {
      const playerNextY = y - 1

      // 玩家方向——向上
      if (direction === DIRECTION_ENUM.TOP) {
        if (Math.abs(playerNextY) > column - 1) {
          this.state = ENTITY_STATE_ENUM.BLOCKBACK
          return true
        }

        const weaponNextY = y
        const nextPlayerTile = tileInfo[x]?.[Math.abs(playerNextY)]
        const nextWeaponTile = tileInfo[x]?.[Math.abs(weaponNextY)]

        // 检测是否碰撞到门
        if (
          ((doorX === x && doorY === playerNextY) || (doorX === x && doorY === weaponNextY)) &&
          doorState !== ENTITY_STATE_ENUM.DEATH
        ) {
          this.state = ENTITY_STATE_ENUM.BLOCKBACK
          return true
        }

        // 检测是否碰撞到敌人
        for (let i = 0; i < enemies.length; i++) {
          const enemy = enemies[i]
          const { x: enemyX, y: enemyY } = enemy

          if (enemyX === x && enemyY === playerNextY) {
            this.state = ENTITY_STATE_ENUM.BLOCKBACK
            return true
          }
        }

        // 判断地裂陷阱
        if (
          bursts.some(burst => burst.x === x && burst.y === playerNextY) &&
          (!nextWeaponTile || nextWeaponTile.turnable)
        ) {
          return false
        }
        // 检测地图元素 碰撞
        if (nextPlayerTile && nextPlayerTile.moveable && (!nextWeaponTile || nextWeaponTile.turnable)) {
          // empty
        } else {
          this.state = ENTITY_STATE_ENUM.BLOCKBACK
          return true
        }

        // 玩家方向——向下
      } else if (direction === DIRECTION_ENUM.BOTTOM) {
        if (Math.abs(playerNextY) > column - 1) {
          this.state = ENTITY_STATE_ENUM.BLOCKFRONT
          return true
        }

        const weaponNextY = y - 2
        const nextPlayerTile = tileInfo[x]?.[Math.abs(playerNextY)]
        const nextWeaponTile = tileInfo[x]?.[Math.abs(weaponNextY)]

        // 检测是否碰撞到门
        if (
          ((doorX === x && doorY === playerNextY) || (doorX === x && doorY === weaponNextY)) &&
          doorState !== ENTITY_STATE_ENUM.DEATH
        ) {
          this.state = ENTITY_STATE_ENUM.BLOCKFRONT
          return true
        }
        // 检测是否碰撞到敌人
        for (let i = 0; i < enemies.length; i++) {
          const enemy = enemies[i]
          const { x: enemyX, y: enemyY } = enemy

          if ((enemyX === x && enemyY === weaponNextY) || (enemyX === x && enemyY === playerNextY)) {
            this.state = ENTITY_STATE_ENUM.BLOCKFRONT
            return true
          }
        }
        // 检测地图元素 碰撞
        if (nextPlayerTile && nextPlayerTile.moveable && (!nextWeaponTile || nextWeaponTile.turnable)) {
          // empty
        } else {
          this.state = ENTITY_STATE_ENUM.BLOCKFRONT
          return true
        }

        // 玩家方向——向左
      } else if (direction === DIRECTION_ENUM.LEFT) {
        if (Math.abs(playerNextY) > column - 1) {
          this.state = ENTITY_STATE_ENUM.BLOCKLEFT
          return true
        }

        const weaponNextX = x - 1
        const weaponNextY = y - 1
        const nextPlayerTile = tileInfo[x]?.[Math.abs(playerNextY)]
        const nextWeaponTile = tileInfo[weaponNextX]?.[Math.abs(weaponNextY)]

        // 检测是否碰撞到门
        if (
          ((doorX === x && doorY === playerNextY) || (doorX === weaponNextX && doorY === weaponNextY)) &&
          doorState !== ENTITY_STATE_ENUM.DEATH
        ) {
          this.state = ENTITY_STATE_ENUM.BLOCKLEFT
          return true
        }
        // 检测是否碰撞到敌人
        for (let i = 0; i < enemies.length; i++) {
          const enemy = enemies[i]
          const { x: enemyX, y: enemyY } = enemy

          if ((enemyX === x && enemyY === playerNextY) || (enemyX === weaponNextX && enemyY === weaponNextY)) {
            this.state = ENTITY_STATE_ENUM.BLOCKLEFT
            return true
          }
        }
        // 检测地图元素 碰撞
        if (nextPlayerTile && nextPlayerTile.moveable && (!nextWeaponTile || nextWeaponTile.turnable)) {
          // empty
        } else {
          this.state = ENTITY_STATE_ENUM.BLOCKLEFT
          return true
        }

        // 玩家方向——向右
      } else if (direction === DIRECTION_ENUM.RIGHT) {
        if (Math.abs(playerNextY) > column - 1) {
          this.state = ENTITY_STATE_ENUM.BLOCKRIGHT
          return true
        }

        const weaponNextX = x + 1
        const weaponNextY = y - 1
        const nextPlayerTile = tileInfo[x]?.[Math.abs(playerNextY)]
        const nextWeaponTile = tileInfo[weaponNextX]?.[Math.abs(weaponNextY)]

        // 检测是否碰撞到门
        if (
          ((doorX === x && doorY === playerNextY) || (doorX === weaponNextX && doorY === weaponNextY)) &&
          doorState !== ENTITY_STATE_ENUM.DEATH
        ) {
          this.state = ENTITY_STATE_ENUM.BLOCKRIGHT
          return true
        }
        // 检测是否碰撞到敌人
        for (let i = 0; i < enemies.length; i++) {
          const enemy = enemies[i]
          const { x: enemyX, y: enemyY } = enemy

          if ((enemyX === x && enemyY === playerNextY) || (enemyX === weaponNextX && enemyY === weaponNextY)) {
            this.state = ENTITY_STATE_ENUM.BLOCKRIGHT
            return true
          }
        }
        // 检测地图元素 碰撞
        if (nextPlayerTile && nextPlayerTile.moveable && (!nextWeaponTile || nextWeaponTile.turnable)) {
          // empty
        } else {
          this.state = ENTITY_STATE_ENUM.BLOCKRIGHT
          return true
        }
      }

      //按钮方向——向左
    } else if (inputDirection === DIRECTION_ENUM.LEFT) {
      const playerNextX = x - 1

      //玩家方向——向上
      if (direction === DIRECTION_ENUM.TOP) {
        //判断是否超出地图
        if (playerNextX < 0) {
          this.state = ENTITY_STATE_ENUM.BLOCKLEFT

          return true
        }

        const weaponNextX = x - 1
        const weaponNextY = y + 1
        const nextPlayerTile = tileInfo[playerNextX]?.[Math.abs(y)]
        const nextWeaponTile = tileInfo[weaponNextX]?.[Math.abs(weaponNextY)]

        // 判断门
        if (
          ((doorX === playerNextX && doorY === y) || (doorX === weaponNextX && doorY === weaponNextY)) &&
          doorState !== ENTITY_STATE_ENUM.DEATH
        ) {
          this.state = ENTITY_STATE_ENUM.BLOCKLEFT
          return true
        }
        // 判断敌人
        for (let i = 0; i < enemies.length; i++) {
          const enemy = enemies[i]
          const { x: enemyX, y: enemyY } = enemy

          if ((enemyX === playerNextX && enemyY === y) || (enemyX === weaponNextX && enemyY === weaponNextY)) {
            this.state = ENTITY_STATE_ENUM.BLOCKLEFT
            return true
          }
        }
        // 判断地图元素
        if (nextPlayerTile && nextPlayerTile.moveable && (!nextWeaponTile || nextWeaponTile.turnable)) {
          // empty
        } else {
          this.state = ENTITY_STATE_ENUM.BLOCKLEFT
          return true
        }

        // 玩家方向——向下
      } else if (direction === DIRECTION_ENUM.BOTTOM) {
        //判断是否超出地图
        if (playerNextX < 0) {
          this.state = ENTITY_STATE_ENUM.BLOCKRIGHT
          return true
        }

        const weaponNextX = x - 1
        const weaponNextY = y - 1
        const nextPlayerTile = tileInfo[playerNextX]?.[Math.abs(y)]
        const nextWeaponTile = tileInfo[weaponNextX]?.[Math.abs(weaponNextY)]

        // 判断门
        if (
          ((doorX === playerNextX && doorY === y) || (doorX === weaponNextX && doorY === weaponNextY)) &&
          doorState !== ENTITY_STATE_ENUM.DEATH
        ) {
          this.state = ENTITY_STATE_ENUM.BLOCKRIGHT
          return true
        }
        // 判断敌人
        for (let i = 0; i < enemies.length; i++) {
          const enemy = enemies[i]
          const { x: enemyX, y: enemyY } = enemy

          if ((enemyX === playerNextX && enemyY === y) || (enemyX === weaponNextX && enemyY === weaponNextY)) {
            this.state = ENTITY_STATE_ENUM.BLOCKRIGHT
            return true
          }
        }
        // 判断地图元素
        if (nextPlayerTile && nextPlayerTile.moveable && (!nextWeaponTile || nextWeaponTile.turnable)) {
          // empty
        } else {
          this.state = ENTITY_STATE_ENUM.BLOCKRIGHT
          return true
        }

        //玩家方向——向左
      } else if (direction === DIRECTION_ENUM.LEFT) {
        //判断是否超出地图
        if (playerNextX < 0) {
          this.state = ENTITY_STATE_ENUM.BLOCKFRONT
          return true
        }

        const weaponNextX = x - 2
        const nextPlayerTile = tileInfo[playerNextX]?.[Math.abs(y)]
        const nextWeaponTile = tileInfo[weaponNextX]?.[Math.abs(y)]

        // 判断门
        if (
          ((doorX === playerNextX && doorY === y) || (doorX === weaponNextX && doorY === y)) &&
          doorState !== ENTITY_STATE_ENUM.DEATH
        ) {
          this.state = ENTITY_STATE_ENUM.BLOCKFRONT
          return true
        }
        // 判断敌人
        for (let i = 0; i < enemies.length; i++) {
          const enemy = enemies[i]
          const { x: enemyX, y: enemyY } = enemy

          if ((enemyX === playerNextX && enemyY === y) || (enemyX === weaponNextX && enemyY === y)) {
            this.state = ENTITY_STATE_ENUM.BLOCKFRONT
            return true
          }
        }
        // 判断地图元素
        if (nextPlayerTile && nextPlayerTile.moveable && (!nextWeaponTile || nextWeaponTile.turnable)) {
          // empty
        } else {
          this.state = ENTITY_STATE_ENUM.BLOCKFRONT
          return true
        }

        // 玩家方向——向右
      } else if (direction === DIRECTION_ENUM.RIGHT) {
        //判断是否超出地图
        if (playerNextX < 0) {
          this.state = ENTITY_STATE_ENUM.BLOCKBACK
          return true
        }

        const weaponNextX = x
        const nextPlayerTile = tileInfo[playerNextX]?.[Math.abs(y)]
        const nextWeaponTile = tileInfo[weaponNextX]?.[Math.abs(y)]

        // 判断门
        if (
          ((doorX === playerNextX && doorY === y) || (doorX === weaponNextX && doorY === y)) &&
          doorState !== ENTITY_STATE_ENUM.DEATH
        ) {
          this.state = ENTITY_STATE_ENUM.BLOCKBACK
          return true
        }
        // 判断敌人
        for (let i = 0; i < enemies.length; i++) {
          const enemy = enemies[i]
          const { x: enemyX, y: enemyY } = enemy

          if (enemyX === playerNextX && enemyY === y) {
            this.state = ENTITY_STATE_ENUM.BLOCKBACK
            return true
          }
        }
        // 判断地图元素
        if (nextPlayerTile && nextPlayerTile.moveable && (!nextWeaponTile || nextWeaponTile.turnable)) {
          // empty
        } else {
          this.state = ENTITY_STATE_ENUM.BLOCKBACK
          return true
        }
      }

      // 按钮方向——向右
    } else if (inputDirection === DIRECTION_ENUM.RIGHT) {
      const playerNextX = x + 1

      //玩家方向——向上
      if (direction === DIRECTION_ENUM.TOP) {
        if (playerNextX > row - 1) {
          this.state = ENTITY_STATE_ENUM.BLOCKRIGHT
          return true
        }

        const weaponNextX = x + 1
        const weaponNextY = y + 1
        const nextPlayerTile = tileInfo[playerNextX]?.[Math.abs(y)]
        const nextWeaponTile = tileInfo[weaponNextX]?.[Math.abs(weaponNextY)]

        // 判断门
        if (
          ((doorX === playerNextX && doorY === y) || (doorX === weaponNextX && doorY === weaponNextY)) &&
          doorState !== ENTITY_STATE_ENUM.DEATH
        ) {
          this.state = ENTITY_STATE_ENUM.BLOCKRIGHT
          return true
        }
        // 判断敌人
        for (let i = 0; i < enemies.length; i++) {
          const enemy = enemies[i]
          const { x: enemyX, y: enemyY } = enemy

          if ((enemyX === playerNextX && enemyY === y) || (enemyX === weaponNextX && enemyY === weaponNextY)) {
            this.state = ENTITY_STATE_ENUM.BLOCKRIGHT
            return true
          }
        }
        // 判断地图元素
        if (nextPlayerTile && nextPlayerTile.moveable && (!nextWeaponTile || nextWeaponTile.turnable)) {
          // empty
        } else {
          this.state = ENTITY_STATE_ENUM.BLOCKRIGHT
          return true
        }

        // 玩家方向——向下
      } else if (direction === DIRECTION_ENUM.BOTTOM) {
        if (playerNextX > row - 1) {
          this.state = ENTITY_STATE_ENUM.BLOCKLEFT
          return true
        }

        const weaponNextX = x + 1
        const weaponNextY = y - 1
        const nextPlayerTile = tileInfo[playerNextX]?.[Math.abs(y)]
        const nextWeaponTile = tileInfo[weaponNextX]?.[Math.abs(weaponNextY)]

        // 判断门
        if (
          ((doorX === playerNextX && doorY === y) || (doorX === weaponNextX && doorY === weaponNextY)) &&
          doorState !== ENTITY_STATE_ENUM.DEATH
        ) {
          this.state = ENTITY_STATE_ENUM.BLOCKLEFT
          return true
        }
        // 判断敌人
        for (let i = 0; i < enemies.length; i++) {
          const enemy = enemies[i]
          const { x: enemyX, y: enemyY } = enemy

          if ((enemyX === playerNextX && enemyY === y) || (enemyX === weaponNextX && enemyY === weaponNextY)) {
            this.state = ENTITY_STATE_ENUM.BLOCKLEFT
            return true
          }
        }
        // 判断地图元素
        if (nextPlayerTile && nextPlayerTile.moveable && (!nextWeaponTile || nextWeaponTile.turnable)) {
          // empty
        } else {
          this.state = ENTITY_STATE_ENUM.BLOCKLEFT
          return true
        }

        // 玩家方向——向左
      } else if (direction === DIRECTION_ENUM.LEFT) {
        if (playerNextX > row - 1) {
          this.state = ENTITY_STATE_ENUM.BLOCKBACK
          return true
        }

        const weaponNextX = x
        const nextPlayerTile = tileInfo[playerNextX]?.[Math.abs(y)]
        const nextWeaponTile = tileInfo[weaponNextX]?.[Math.abs(y)]

        //判断门
        if (
          ((doorX === playerNextX && doorY === y) || (doorX === weaponNextX && doorY === y)) &&
          doorState !== ENTITY_STATE_ENUM.DEATH
        ) {
          this.state = ENTITY_STATE_ENUM.BLOCKBACK
          return true
        }
        //判断敌人
        for (let i = 0; i < enemies.length; i++) {
          const enemy = enemies[i]
          const { x: enemyX, y: enemyY } = enemy

          if (enemyX === playerNextX && enemyY === y) {
            this.state = ENTITY_STATE_ENUM.BLOCKBACK
            return true
          }
        }
        // 判断地图元素
        if (nextPlayerTile && nextPlayerTile.moveable && (!nextWeaponTile || nextWeaponTile.turnable)) {
          // empty
        } else {
          this.state = ENTITY_STATE_ENUM.BLOCKBACK
          return true
        }

        // 玩家方向——向右
      } else if (direction === DIRECTION_ENUM.RIGHT) {
        if (playerNextX > row - 1) {
          this.state = ENTITY_STATE_ENUM.BLOCKFRONT
          return true
        }

        const weaponNextX = x + 2
        const nextPlayerTile = tileInfo[playerNextX]?.[Math.abs(y)]
        const nextWeaponTile = tileInfo[weaponNextX]?.[Math.abs(y)]

        // 判断门
        if (
          ((doorX === playerNextX && doorY === y) || (doorX === weaponNextX && doorY === y)) &&
          doorState !== ENTITY_STATE_ENUM.DEATH
        ) {
          this.state = ENTITY_STATE_ENUM.BLOCKFRONT
          return true
        }
        // 判断敌人
        for (let i = 0; i < enemies.length; i++) {
          const enemy = enemies[i]
          const { x: enemyX, y: enemyY } = enemy

          if ((enemyX === playerNextX && enemyY === y) || (enemyX === weaponNextX && enemyY === y)) {
            this.state = ENTITY_STATE_ENUM.BLOCKFRONT
            return true
          }
        }
        // 判断地图元素
        if (nextPlayerTile && nextPlayerTile.moveable && (!nextWeaponTile || nextWeaponTile.turnable)) {
          // empty
        } else {
          this.state = ENTITY_STATE_ENUM.BLOCKFRONT
          return true
        }
      }

      // 按钮方向——左转
    } else if (inputDirection === DIRECTION_ENUM.TURNLEFT) {
      let nextY, nextX
      //朝上左转的话，左上角三个tile都必须turnable为true，并且没有敌人
      if (direction === DIRECTION_ENUM.TOP) {
        nextY = y + 1 // 面朝上 往左一格的位置 x不变 y+1向上一格
        nextX = x - 1 // 面朝上 往前一格的位置 y不变 x-1向左一格
      } else if (direction === DIRECTION_ENUM.BOTTOM) {
        nextY = y - 1 // 面朝下 往下一格位置 x不变 y-1向下一格
        nextX = x + 1 // 面朝下 往右一格位置 y不变 x+1向右一格
      } else if (direction === DIRECTION_ENUM.LEFT) {
        nextY = y - 1 // 面朝左 往下一格位置 x不变 y-1向下一格
        nextX = x - 1 // 面朝左 往前一格位置 y不变 x-1向左一格
      } else if (direction === DIRECTION_ENUM.RIGHT) {
        nextY = y + 1 // 面朝右 往上一格位置 x不变 y+1向上一格
        nextX = x + 1 // 面朝右 往前一格位置 y不变 x+1向右一格
      }

      // 判断门
      if (
        ((doorX === x && doorY === nextY) ||
          (doorX === nextX && doorY === y) ||
          (doorX === nextX && doorY === nextY)) &&
        doorState !== ENTITY_STATE_ENUM.DEATH
      ) {
        this.state = ENTITY_STATE_ENUM.BLOCKTURNLEFT
        return true
      }

      // 判断敌人
      for (let i = 0; i < enemies.length; i++) {
        const enemy = enemies[i]
        const { x: enemyX, y: enemyY } = enemy
        if (enemyX === nextX && enemyY === y) {
          this.state = ENTITY_STATE_ENUM.BLOCKTURNLEFT
          return true
        } else if (enemyX === nextX && enemyY === nextY) {
          this.state = ENTITY_STATE_ENUM.BLOCKTURNLEFT
          return true
        } else if (enemyX === x && enemyY === nextY) {
          this.state = ENTITY_STATE_ENUM.BLOCKTURNLEFT
          return true
        }
      }
      // 判断地图元素
      // 下面这个逻辑，其实就是判断武器所在的瓦片地图是否可以旋转。
      // 需要三个方向 根据朝向不同具体方位不同，但是都是上(下)、斜上(斜下)、左(右)这三个瓦片
      // if语句的逻辑顺序，分别是判断上(下)、斜上(斜下)、左(右)的瓦片是否可以旋转
      if (
        (!tileInfo[x]?.[Math.abs(nextY)] || tileInfo[x]?.[Math.abs(nextY)].turnable) &&
        (!tileInfo[nextX]?.[Math.abs(nextY)] || tileInfo[nextX]?.[Math.abs(nextY)].turnable) &&
        (!tileInfo[nextX]?.[Math.abs(y)] || tileInfo[nextX]?.[Math.abs(y)].turnable)
      ) {
        // empty
      } else {
        this.state = ENTITY_STATE_ENUM.BLOCKTURNLEFT
        return true
      }

      // 按钮方向——右转
    } else if (inputDirection === DIRECTION_ENUM.TURNRIGHT) {
      let nextX, nextY
      // 朝上右转的话，右上角三个tile都必须turnable为true
      if (direction === DIRECTION_ENUM.TOP) {
        nextY = y + 1
        nextX = x + 1
      } else if (direction === DIRECTION_ENUM.BOTTOM) {
        nextY = y - 1
        nextX = x - 1
      } else if (direction === DIRECTION_ENUM.LEFT) {
        nextY = y + 1
        nextX = x - 1
      } else if (direction === DIRECTION_ENUM.RIGHT) {
        nextY = y - 1
        nextX = x + 1
      }

      // 判断门
      if (
        ((doorX === x && doorY === nextY) ||
          (doorX === nextX && doorY === y) ||
          (doorX === nextX && doorY === nextY)) &&
        doorState !== ENTITY_STATE_ENUM.DEATH
      ) {
        this.state = ENTITY_STATE_ENUM.BLOCKTURNRIGHT
        return true
      }

      // 判断敌人
      for (let i = 0; i < enemies.length; i++) {
        const enemy = enemies[i]
        const { x: enemyX, y: enemyY } = enemy

        if (enemyX === nextX && enemyY === y) {
          this.state = ENTITY_STATE_ENUM.BLOCKTURNRIGHT
          return true
        } else if (enemyX === nextX && enemyY === nextY) {
          this.state = ENTITY_STATE_ENUM.BLOCKTURNRIGHT
          return true
        } else if (enemyX === x && enemyY === nextY) {
          this.state = ENTITY_STATE_ENUM.BLOCKTURNRIGHT
          return true
        }
      }
      // 判断地图元素
      // 下面这个逻辑，其实就是判断武器所在的瓦片地图是否可以旋转。
      if (
        (!tileInfo[x]?.[Math.abs(nextY)] || tileInfo[x]?.[Math.abs(nextY)].turnable) &&
        (!tileInfo[nextX]?.[Math.abs(y)] || tileInfo[nextX]?.[Math.abs(y)].turnable) &&
        (!tileInfo[nextX]?.[Math.abs(nextY)] || tileInfo[nextX]?.[Math.abs(nextY)].turnable)
      ) {
        // empty
      } else {
        this.state = ENTITY_STATE_ENUM.BLOCKTURNRIGHT
        return true
      }
    }

    return false
  }

  /** 玩家攻击敌人时触发的帧动画事件 */
  onAttackShake(direction: DIRECTION_ENUM) {
    console.log('direction', direction)

    EventMgr.Instance.emit(EVENT_NAME_ENUM.SCREEN_SHAKE, direction) // 地图触发震动
  }

  onDestroy(): void {
    EventMgr.Instance.off(EVENT_NAME_ENUM.CONTROLLER_MOVE, this.inputHandle)
    EventMgr.Instance.off(EVENT_NAME_ENUM.ATTACK_PLAYER, this.handlePlayerDead)
  }
}
